#include "guiterm.hpp"

FileTransferView::FileTransferView(RemoteJob *owner, FileTransfer *transfer)
	:JobViewSegment(owner)
{
	this->transfer = transfer;
	
	connect(transfer, SIGNAL(listReady(const vector<string>&)), this, SLOT(listReady(const vector<string>&)));
	connect(transfer, SIGNAL(transferBegun()), this, SLOT(transferBegun()));
	connect(transfer, SIGNAL(fileBegun(string)), this, SLOT(fileBegun(string)));
	connect(transfer, SIGNAL(updateProgress(string,double)), this, SLOT(updateProgress(string,double)));
	connect(transfer, SIGNAL(fileFailed(string,string)), this, SLOT(fileFailed(string,string)));
	connect(transfer, SIGNAL(fileFinished(string)), this, SLOT(fileFinished(string)));
	connect(transfer, SIGNAL(transferFinished(bool,string)), this, SLOT(transferFinished(bool,string)));
	
	QVBoxLayout *layout = new QVBoxLayout();
	layout->setSpacing(0);
	layout->setContentsMargins(0,0,0,0);
	setLayout(layout);
	
	WidgetFrame *frame = new WidgetFrame(this);
	layout->addWidget(frame);
	
	this->frameLayout = new QVBoxLayout();
	frame->setLayout(frameLayout);
	
	this->destLineLayout = NULL;
	this->destLineLabel = NULL;
	this->destLocationEdit = NULL;
	this->browseDialog = NULL;
	this->browseButton = NULL;
	this->cancelButton = NULL;
}

FileTransferView::~FileTransferView()
{
	for(size_t ii=0; ii<lines.size(); ii++) {
		delete lines[ii]->label;
		delete lines[ii]->progress;
		delete lines[ii]->layout;
	}
	
	delete destLineLayout;
	delete destLineLabel;
	delete destLocationEdit;
	delete browseDialog;
	delete browseButton;
	delete actionsLineLayout;
	delete okButton;
	delete cancelButton;
	
	delete frameLayout;
}

void FileTransferView::begin()
{
	setLocationLineDisabled(true);
	okButton->setDisabled(true);
	cancelButton->setDisabled(true);
	
	string destLocation = destLocationEdit->text().toStdString();
	transfer->begin(destLocation);
}

void FileTransferView::cancel()
{
	setLocationLineDisabled(true);
	okButton->setDisabled(true);
	cancelButton->setDisabled(true);
	
	job->finishSegment();
}

void FileTransferView::togglePaused()
{
	if(transfer->isPaused()) {
		pauseButton->setText("Pause");
		transfer->resume();
	} else {
		pauseButton->setText("Resume");
		transfer->pause();
	}
}

void FileTransferView::browse()
{
	if(browseDialog)
		delete browseDialog;
	
	TerminalWindow *parentWindow = getSession()->getTab()->getWindow();
	
	browseDialog = new QFileDialog(parentWindow, "Download Directory", destLocationEdit->text());
	browseDialog->setFileMode(QFileDialog::DirectoryOnly);
	connect(browseDialog, SIGNAL(fileSelected(QString)), this, SLOT(browseDialogPicked(QString)));

	browseDialog->exec();
}

void FileTransferView::browseDialogPicked(QString dir)
{
	destLocationEdit->setText(dir);
}

void FileTransferView::listReady(const vector<string> &files)
{
	string fileListStr;
	for(unsigned ii=0; ii<files.size(); ii++) {
		if(ii) fileListStr += "\n";
		fileListStr += files[ii];
	}
	
	QLabel *fileListLabel = new QLabel(fileListStr.c_str());
	frameLayout->addWidget(fileListLabel);
	
	destLineLayout = new QHBoxLayout();
	destLineLayout->setSpacing(2);
	destLineLayout->setContentsMargins(0,0,0,0);
	frameLayout->addLayout(destLineLayout);
	
	destLineLabel = new QLabel(transfer->isUpload() ? "Upload from:" : "Download to:");
	destLineLayout->addWidget(destLineLabel);
	
	destLocationEdit = new QLineEdit(session->getLocalDir().c_str());
	destLineLayout->addWidget(destLocationEdit);
	connect(destLocationEdit, SIGNAL(returnPressed()), this, SLOT(begin()));
	
	browseButton = new QPushButton("Browse");
	connect(browseButton, SIGNAL(clicked()), this, SLOT(browse()));
	destLineLayout->addWidget(browseButton);
	
	actionsLineLayout = new QHBoxLayout();
	actionsLineLayout->setContentsMargins(0,0,0,0);
	frameLayout->addLayout(actionsLineLayout);
	
	actionsLineLayout->addStretch(1);
	
	okButton = new QPushButton("OK");
	connect(okButton, SIGNAL(clicked()), this, SLOT(begin()));
	actionsLineLayout->addWidget(okButton);
	
	cancelButton = new QPushButton("Cancel");
	connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
	actionsLineLayout->addWidget(cancelButton);
	
	actionsLineLayout->addStretch(1);
	
	destLocationEdit->setFocus();
}

void FileTransferView::transferBegun()
{
	progressLayout = new QVBoxLayout();
		progressLayout->setSpacing(0);
	frameLayout->addLayout(progressLayout);
	
	statusLineLayout = new QHBoxLayout();
	statusLineLayout->setContentsMargins(0,0,0,0);
	
	statusLabel = new QLabel(transfer->isUpload() ? "Uploading" : "Downloading");
	statusLineLayout->addWidget(statusLabel);
	
	statusLineLayout->addStretch(1);
	
	pauseButton = new QPushButton("Pause");
	connect(pauseButton, SIGNAL(clicked()), this, SLOT(togglePaused()));
	//statusLineLayout->addWidget(pauseButton);

	cancelTransferButton = new QPushButton("Cancel");
	connect(cancelTransferButton, SIGNAL(clicked()), transfer, SLOT(cancel()));
	statusLineLayout->addWidget(cancelTransferButton);
	
	frameLayout->addLayout(statusLineLayout);
}

void FileTransferView::fileBegun(string file)
{
	ProgressLine *progressLine = new ProgressLine();
	lines.push_back(progressLine);
	progressLine->layout = new QHBoxLayout();
		progressLine->layout->setContentsMargins(0,0,0,0);
	progressLine->label = new QLabel(file.c_str());
		progressLine->layout->addWidget(progressLine->label);
	progressLine->progress = new QProgressBar();
		progressLine->progress->setMaximum(FILETRANSFER_PROGRESS_MAX);
		progressLine->layout->addWidget(progressLine->progress);
	progressLayout->addLayout(progressLine->layout);
}

void FileTransferView::updateProgress(string filename, double progress)
{
	if(!lines.size()) return;
	QProgressBar *progressBar = lines[lines.size()-1]->progress;
	
	// The maximum might be more than INT_MAX (if the file's over 4GB), so the
	// progress bar has a numeric scale from 0-10,000 rather than using bytes
	progressBar->setValue((int)(progress * FILETRANSFER_PROGRESS_MAX));
}

void FileTransferView::fileFailed(string filename, string message)
{
	ProgressLine *progressLine = new ProgressLine();
	lines.push_back(progressLine);
	progressLine->layout = new QHBoxLayout();
		progressLine->layout->setContentsMargins(0,0,0,0);
	string combinedMessage = retprintf("Downloading %s failed: %s.", filename.c_str(), message.c_str());
	progressLine->label = new QLabel(combinedMessage.c_str());
		progressLine->layout->addWidget(progressLine->label);
	frameLayout->addLayout(progressLine->layout);
}

void FileTransferView::fileFinished(string filename)
{
}

void FileTransferView::transferFinished(bool successful, string message)
{
	statusLabel->setText(message.c_str());
	if(!successful)
		statusLabel->setPalette(*PaletteManager::errorMessage());
	
	pauseButton->setDisabled(true);
	cancelTransferButton->setDisabled(true);
	
	job->finishSegment();
}

void FileTransferView::setLocationLineDisabled(bool disabled)
{
	destLocationEdit->setDisabled(disabled);
	browseButton->setDisabled(disabled);
}

